<?php

namespace App\Libraries\DingTalk;

use App\Libraries\DingTalk\Crypt\DingCallbackCrypto;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Cache;

class DingTalkBase
{
    public $dingtalkConfig;

    public $dingtalkCrypto;

    public $client;

    public function __construct()
    {
        $this->dingtalkConfig = config('services.dingtalk');
        $this->dingtalkCrypto = new DingCallbackCrypto(
            $this->dingtalkConfig['token'],
            $this->dingtalkConfig['aes_key'],
            $this->dingtalkConfig['app_key']
        );
        $this->client = new Client(['timeout' => 10]);
    }

    public function getAccessToken(): string
    {
        $cacheKey = 'string:dingtalk:access_token:' . $this->dingtalkConfig['app_key'];
        if (Cache::has($cacheKey)) {
            return Cache::get($cacheKey);
        }

        $response = $this->client->post('https://api.dingtalk.com/v1.0/oauth2/accessToken', [
            'headers' => [
                'Content-Type' => 'application/json;',
            ],
            'json' => [
                'appKey' => $this->dingtalkConfig['app_key'],
                'appSecret' => $this->dingtalkConfig['app_secret'],
            ],
        ]);
        $content = $response->getBody()->getContents();
        $content = json_decode($content, true);

        $accessToken = $content['accessToken'];

        Cache::put($cacheKey, $accessToken, 6000);

        return $accessToken;
    }

    public function getDecryptMsg(string $signature, string $timestamp, string $nonce, string $encrypt): array
    {
        $text = $this->dingtalkCrypto->getDecryptMsg($signature, $timestamp, $nonce, $encrypt);

        return json_decode($text, true);
    }

    public function getEncryptedMap(string $plain = 'success'): string
    {
        return $this->dingtalkCrypto->getEncryptedMap($plain);
    }

    public function requestByGet(string $uri, array $options): array
    {
        $response = $this->client->get($uri, $options);
        $content = $response->getBody()->getContents();

        return json_decode($content, true);
    }

    public function requestByPost(string $uri, array $params): array
    {
        $response = $this->client->post($uri, $params);
        $content = $response->getBody()->getContents();

        return json_decode($content, true);
    }
}
